import * as vscode from 'vscode';
import * as path from 'path';
import * as fs from 'fs';

// 表示文件或目录的树节点
class FileSystemItem extends vscode.TreeItem {
    constructor(
        public readonly resourceUri: vscode.Uri,
        public readonly isDirectory: boolean
    ) {
        // 设置图标
        super(
            resourceUri,
            isDirectory
                ? vscode.TreeItemCollapsibleState.Collapsed
                : vscode.TreeItemCollapsibleState.None
        );

        // 设置标签为文件名
        this.label = path.basename(resourceUri.fsPath);

        this.contextValue = isDirectory ? 'directory' : 'file';

        // 对于文件，添加点击打开命令
        if (!isDirectory) {
            this.command = {
                command: 'vscode.open',
                title: 'Open File',
                arguments: [resourceUri]
            };
        }  
    }
}

// TreeView 数据提供者 - This class acts as an Adapter between the filesystem and VS Code's TreeView
class FileSystemAdapter implements vscode.TreeDataProvider<FileSystemItem> {
    private _onDidChangeTreeData: vscode.EventEmitter<FileSystemItem | undefined | null | void> =
        new vscode.EventEmitter<FileSystemItem | undefined | null | void>();

    readonly onDidChangeTreeData: vscode.Event<FileSystemItem | undefined | null | void> =
        this._onDidChangeTreeData.event;

    constructor(private workspaceRoot: string | undefined) { }

    refresh(): void {
        this._onDidChangeTreeData.fire();
    }

    getTreeItem(element: FileSystemItem): vscode.TreeItem {
        return element;
    }

    async getChildren(element?: FileSystemItem): Promise<FileSystemItem[]> {
        // 如果没有打开工作区或无目录路径，则返回空数组
        if ((!this.workspaceRoot && !element) || (!element?.resourceUri.fsPath && !this.workspaceRoot)) {
            return [];
        }

        // 获取目录路径
        const directoryPath = element ? element.resourceUri.fsPath : this.workspaceRoot;

        // 读取目录内容
        const files = await fs.promises.readdir(directoryPath!);

        // 适配过程：将文件系统项转换为VS Code TreeView项
        const children = await Promise.all(
            files.map(async file => {
                const filePath = path.join(directoryPath!, file);
                const stat = await fs.promises.stat(filePath);
                return new FileSystemItem(
                    vscode.Uri.file(filePath),
                    stat.isDirectory()
                );
            })
        );

        // 文件夹优先排序
        return children.sort((a, b) => {
            if (a.isDirectory && !b.isDirectory) return -1;
            if (!a.isDirectory && b.isDirectory) return 1;
            return (a.label as string).localeCompare(b.label as string);
        });
    }
}

export function activate(context: vscode.ExtensionContext) {
    // 获取当前工作区根目录
    const workspaceRoot = vscode.workspace.workspaceFolders
        ? vscode.workspace.workspaceFolders[0].uri.fsPath
        : undefined;

    // 创建适配器实例
    const finderAdapter = new FileSystemAdapter(workspaceRoot);

    // 注册树视图
    const treeView = vscode.window.createTreeView('designpattern.finder', {
        treeDataProvider: finderAdapter,
        showCollapseAll: true
    });

    // 注册刷新命令
    const refreshCommand = vscode.commands.registerCommand('finder.refresh', () => {
        finderAdapter.refresh();
    });

    // 通过监听事件主动刷新

    if (workspaceRoot) {
        const watcher = vscode.workspace.createFileSystemWatcher(
            new vscode.RelativePattern(workspaceRoot, '**'),
            false,  // 不忽略创建事件
            false,  // 不忽略修改事件
            false   // 不忽略删除事件
        );

        // 注册文件系统变化监听器
        watcher.onDidCreate(() => vscode.commands.executeCommand('finder.refresh'));
        watcher.onDidChange(() => vscode.commands.executeCommand('finder.refresh'));
        watcher.onDidDelete(() => vscode.commands.executeCommand('finder.refresh'));

        context.subscriptions.push(watcher);
    }

    // 添加到订阅中
    context.subscriptions.push(treeView, refreshCommand);
}